home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_02 / misc / ttt3d.c < prev    next >
C/C++ Source or Header  |  1994-03-20  |  5KB  |  301 lines

  1. /*
  2.  * 3D Tic Tac Toe.
  3.  *
  4.  * Original Author Unknown
  5.  *
  6.  * Compile command: cc ttt3d -fop
  7.  */
  8. #include <stdio.h>
  9.  
  10. #define    EMPTY    0
  11. #define    PLAYER    1
  12. #define    BEAST    5
  13.  
  14. /*
  15.  * This is a table of all winning combinations.
  16.  * From Kilobaud, April 78.
  17.  * You can look there to see how it is ordered.
  18.  */
  19. char w[] = {
  20.     0,    1,    2,    3,
  21.     4,    5,    6,    7,
  22.     8,    9,    10,    11,
  23.     12,    13,    14,    15,
  24.     0,    4,    8,    12,
  25.     1,    5,    9,    13,
  26.     2,    6,    10,    14,
  27.     3,    7,    11,    15,
  28.     0,    5,    10,    15,
  29.     3,    6,    9,    12,
  30.     16,    17,    18,    19,
  31.     20,    21,    22,    23,
  32.     24,    25,    26,    27,
  33.     28,    29,    30,    31,
  34.     16,    20,    24,    28,
  35.     17,    21,    25,    29,
  36.     18,    22,    26,    30,
  37.     19,    23,    27,    31,
  38.     16,    21,    26,    31,
  39.     19,    22,    25,    28,
  40.     32,    33,    34,    35,
  41.     36,    37,    38,    39,
  42.     40,    41,    42,    43,
  43.     44,    45,    46,    47,
  44.     32,    36,    40,    44,
  45.     33,    37,    41,    45,
  46.     34,    38,    42,    46,
  47.     35,    39,    43,    47,
  48.     32,    37,    42,    47,
  49.     35,    38,    41,    44,
  50.     48,    49,    50,    51,
  51.     52,    53,    54,    55,
  52.     56,    57,    58,    59,
  53.     60,    61,    62,    63,
  54.     48,    52,    56,    60,
  55.     49,    53,    57,    61,
  56.     50,    54,    58,    62,
  57.     51,    55,    59,    63,
  58.     48,    53,    58,    63,
  59.     51,    54,    57,    60,
  60.     0,    16,    32,    48,
  61.     1,    17,    33,    49,
  62.     2,    18,    34,    50,
  63.     3,    19,    35,    51,
  64.     4,    20,    36,    52,
  65.     5,    21,    37,    53,
  66.     6,    22,    38,    54,
  67.     7,    23,    39,    55,
  68.     8,    24,    40,    56,
  69.     9,    25,    41,    57,
  70.     10,    26,    42,    58,
  71.     11,    27,    43,    59,
  72.     13,    29,    45,    61,
  73.     12,    28,    44,    60,
  74.     14,    30,    46,    62,
  75.     15,    31,    47,    63,
  76.     0,    21,    42,    63,
  77.     4,    21,    38,    55,
  78.     8,    25,    42,    59,
  79.     12,    25,    38,    51,
  80.     1,    21,    41,    61,
  81.     13,    25,    37,    49,
  82.     2,    22,    42,    62,
  83.     14,    26,    38,    50,
  84.     3,    22,    41,    60,
  85.     7,    22,    37,    52,
  86.     11,    26,    41,    56,
  87.     15,    26,    37,    48,
  88.     0,    20,    40,    60,
  89.     0,    17,    34,    51,
  90.     3,    18,    33,    48,
  91.     3,    23,    43,    63,
  92.     12,    24,    36,    48,
  93.     12,    29,    46,    63,
  94.     15,    30,    45,    60,
  95.     15,    27,    39,    51
  96. };
  97.  
  98. /*
  99.  * This is the board.
  100.  * Starts off all empty.
  101.  */
  102. char    b[64] = 0;
  103. char    sep[] = "  -----------  -----------  -----------  -----------\n";
  104.  
  105. /*
  106.  * The mainline is just a driver.
  107.  */
  108. main()
  109. {
  110.     char buf[20];
  111.  
  112.     printf("Do you want the rules? ");
  113.     fgets(buf, 20, stdin);
  114.     if(buf[0]=='Y' || buf[0]=='y')
  115.         rules();
  116.     printf("Do you want to go first? ");
  117.     fgets(buf,20,stdin);
  118.     if(buf[0]=='Y' || buf[0]=='y')
  119.         user();
  120.     for(;;) {
  121.         beast();
  122.         user();
  123.     }
  124. }
  125.  
  126. /*
  127.  * Print the rules of the game.
  128.  */
  129. rules()
  130. {
  131.     printf("Three dimensional tic-tac-toe is played on a 4x4x4\n");
  132.     printf("board. To win you must get 4 in a row.  Your moves\n");
  133.     printf("are specified as a 3 digit number; the first digit\n");
  134.     printf("is the level, the second the row and the third the\n");
  135.     printf("column. Levels and columns  go  from left to right\n");
  136.     printf("from 1 to 3. Rows go from top to bottom with  0 on\n");
  137.     printf("the top.\n");
  138. }
  139.  
  140. /*
  141.  * Accept a user move. Exit if he wins.
  142.  */
  143. user()
  144. {
  145.     register int i, j, t;
  146.     char buf[20];
  147.  
  148.     board();
  149.     for(;;) {
  150.         printf("Your move (L/R/C)? ");
  151.         if(!fgets(buf,20,stdin)) {
  152.             printf("Chicken.\n");
  153.             exit(0);
  154.         }
  155.         i = 16*(buf[0]-'1') + (buf[1]-'1') + 4*(buf[2]-'1');
  156.         if(i>=0 && i<=63 && b[i]==EMPTY)
  157.             break;
  158.         printf("Eh?\n");
  159.     }
  160.     b[i] = PLAYER;
  161.     for(i=0; i<4*76; i+=4) {
  162.         t = 0;
  163.         for(j=0; j<4; ++j)
  164.             t += b[w[i+j]];
  165.         if(t == 4*PLAYER) {
  166.             printf("You win.\n");
  167.             exit(0);
  168.         }
  169.     }
  170. }
  171.  
  172. /*
  173.  * Display the board. (Not as easy as it sounds)
  174.  */
  175. board()
  176. {
  177.     register int i, j;
  178.  
  179.     for(i=1; i < 5; ++i)
  180.         printf("       %d     ", i);
  181.     printf("\n");
  182.     for(i=0; i<4; ++i) {
  183.         printf(sep);
  184.         printf("%d ", i+1);
  185.         for(j=0; j<64; j+=4) {
  186.             psq(i+j);
  187.             if(j==12 || j==28 || j==44)
  188.                 printf("  ");
  189.             else if(j >= 60)
  190.                 putc('\n', stdout);
  191.             else
  192.                 putc('!', stdout);
  193.         }
  194.     }
  195.     printf(sep);
  196.     for(i=0; i < 4; ++i) {
  197.         for(j=1; j < 5; ++j)
  198.             printf("  %d", j);
  199.         printf(" "); }
  200.     printf("\n");
  201. }
  202.  
  203. /*
  204.  * Format and put out square `s' of the board.
  205.  */
  206. psq(s)
  207.     int s;
  208. {
  209.     register int v;
  210.  
  211.     v = b[s];
  212.     if(v == PLAYER)
  213.         printf("PP");
  214.     else if(v == BEAST)
  215.         printf("CC");
  216.     else
  217.         printf("  ");
  218. }
  219.  
  220. /*
  221.  * Move for the machine. Just exit on machine wins and draws.
  222.  */
  223. beast()
  224. {
  225.     register int i, j, t;
  226.     int s, bs, bt, v[76];
  227.  
  228.     for(i=0; i<4*76; i+=4) {
  229.         t = 0;
  230.         for(j=0; j<4; ++j)
  231.             t += b[w[i+j]];
  232.         v[i>>2] = t;
  233.         if(t == 3*BEAST)
  234.             break;
  235.     }
  236.     if(i < 4*76) {
  237.         for(j=0; j<4; ++j)
  238.             if(b[w[i+j]] == EMPTY) {
  239.                 b[w[i+j]] = BEAST;
  240.                 break;
  241.             }
  242.         board();
  243.         printf("I win.\n");
  244.         exit(0);
  245.     }
  246.     bt = 0;
  247.     for(s=0; s<64; ++s) {
  248.         if(b[s] != EMPTY)
  249.             continue;
  250.         t = 0;
  251.         for(i=0; i<4*76; i+=4) {
  252.             for(j=0; j<4; ++j)
  253.                 if(w[i+j] == s)
  254.                     break;
  255.             if(j != 4) {
  256.                 if(v[i>>2] == 3*PLAYER) {
  257.                     b[s] = BEAST;
  258.                     return;
  259.                 }
  260.                 t += weight(v[i>>2]);
  261.             }
  262.         }
  263.         if(t > bt) {
  264.             bt = t;
  265.             bs = s;
  266.         }
  267.     }
  268.     if(bt != 0)
  269.         b[bs] = BEAST;
  270.     else {
  271.         for(s=0; s<64; ++s)
  272.             if(b[s] == EMPTY)
  273.                 break;
  274.         if(s == 64) {
  275.             printf("Draw.\n");
  276.             exit(0);
  277.         }
  278.         b[s] = BEAST;
  279.     }
  280. }
  281.  
  282. /*
  283.  * Given a total along a winning combination, return the weight value.
  284.  */
  285. weight(at)
  286.     int at;
  287. {
  288.     register int t;
  289.  
  290.     t = at;
  291.     if(t == PLAYER)
  292.         return(1);
  293.     if(t == 2*PLAYER)
  294.         return(4);
  295.     if(t == BEAST)
  296.         return(1);
  297.     if(t == 2*BEAST)
  298.         return(2);
  299.     return(0);
  300. }
  301.